package com.gitee.baqkft.code.ui.component;

import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import com.gitee.baqkft.code.ui.layout.GBC;

/**
 * 数据连接配置组件
 * @author chenmingcai
 * @date 2018年5月19日 上午10:40:09 
 *
 */

public class ConnectionSettingPanel extends JPanel implements ItemListener
{
	private static final long serialVersionUID = 1L;
	
	/**
	 * 数据库系统名称
	 */
	private static final String DB_MY_SQL = "MySQL";
	private static final String DB_SQL_SERVER = "SQL Server";
	private static final String DB_ORACLE = "Oracle";
	private static final String DB_POSTGRESQL = "PostgreSQL";
	
	/**
	 * 驱动表
	 */
	private static final Map<String, String> driversMap = new HashMap<String, String>(){
		private static final long serialVersionUID = 1L;
		{
			//MySQL supported
			put(DB_MY_SQL, "com.mysql.cj.jdbc.Driver");
			
			//SQL Server supported
			put(DB_SQL_SERVER, "com.microsoft.sqlserver.jdbc.SQLServerDriver");
			
			//Oracle supported
			put(DB_ORACLE, "oracle.jdbc.driver.OracleDriver");

			//PostgreSQL
			put(DB_POSTGRESQL, "org.postgresql.Driver");
		}
	};

	/**
	 * 默认端口表
	 */
	private static final Map<String, String> portsTable = new HashMap<String, String>()
	{
		{
			put(DB_MY_SQL, "3306");
			put(DB_SQL_SERVER, "1433");
			put(DB_ORACLE, "1521");
			put(DB_POSTGRESQL, "5432");
		}
	};

	
	/**
	 * 数据连接接口
	 * @author chenmingcai
	 * @date 2018年5月19日 上午11:42:34 
	 *
	 */
	public interface ConnectionAction
	{
		/**
		 * 数据连接
		 * @param jdbcUrl
		 * @param user
		 * @param password
		 */
		void onConnect(String driver, String jdbcUrl, String user, String password);
	}
	
	/**
	 * 数据库类型
	 */
	private JComboBox<String> dbTypes;
	
	/**
	 * 服务器
	 */
	private JTextField server;
	
	/**
	 * 端口
	 */
	private JTextField port;
	
	/**
	 * 数据库
	 */
	private JTextField db;
	
	/**
	 * 账号
	 */
	private JTextField user;
	
	/**
	 * 密码
	 */
	private JPasswordField password;
	
	/**
	 * 连接按钮接口
	 */
	private ConnectionAction onConnectionAction;
	
	public ConnectionSettingPanel()
	{
		//设置界面
		setLayout(new GridBagLayout());
		JPanel row = new JPanel();
		GBC gbc = new GBC(0, 2).setWeight(1, 0).setFill(GBC.HORIZONTAL).setInsets(2, 0, 0, 0);
		add(row, gbc);
		
		row.setLayout(new GridBagLayout());
		
		JLabel label = new JLabel("类型:");
		gbc = new GBC(0, 0).setWeight(0, 0);
		row.add(label, gbc);

		String[] dbTypeList = new String[driversMap.size()];
		driversMap.keySet().toArray(dbTypeList);
		Arrays.sort(dbTypeList);
		dbTypes = new JComboBox<>(dbTypeList);
		gbc = new GBC(10, 0).setWeight(0, 0);
		row.add(dbTypes, gbc);
		
		label = new JLabel("主机:");
		gbc = new GBC(20, 0).setWeight(0, 0);
		row.add(label, gbc);
		
		server = new JTextField("localhost");
		gbc = new GBC(30, 0).setWeight(2, 0).setFill(GBC.HORIZONTAL);
		row.add(server, gbc);
		
		label = new JLabel("端口:");
		gbc = new GBC(50, 0).setWeight(0, 0);
		row.add(label, gbc);
		
		port = new JTextField("3306");
		gbc = new GBC(60, 0).setWeight(1, 0).setFill(GBC.HORIZONTAL);
		row.add(port, gbc);
		
		row = new JPanel(new GridBagLayout());
		gbc = new GBC(0, 1).setWeight(1, 0).setFill(GBC.HORIZONTAL).setInsets(5, 0, 0, 0);
		add(row, gbc);
		
		label = new JLabel("数据库:");
		gbc = new GBC(0, 0).setWeight(0, 0);
		row.add(label, gbc);
		
		db = new JTextField("test");
		gbc = new GBC(10, 0).setWeight(1, 0).setFill(GBC.HORIZONTAL);
		row.add(db, gbc);
		
		label = new JLabel("账号:");
		gbc = new GBC(30, 0).setWeight(0, 0);
		row.add(label, gbc);
		
		user = new JTextField("root");
		gbc = new GBC(40, 0).setWeight(1, 0).setFill(GBC.HORIZONTAL);
		row.add(user, gbc);
		
		label = new JLabel("密码:");
		gbc = new GBC(60, 0).setWeight(0, 0);
		row.add(label, gbc);
		
		password = new JPasswordField();
		gbc = new GBC(70, 0).setWeight(1, 0).setFill(GBC.HORIZONTAL);
		row.add(password, gbc);
		
		JButton conn = new JButton("连接");
		gbc = new GBC(90, 0).setWeight(0, 0);
		row.add(conn, gbc);
		
		setBorder(BorderFactory.createTitledBorder("连接配置"));
		
		//事件配置
		conn.addActionListener(e -> {
			if(onConnectionAction != null)
			{
				String driver = driversMap.get(dbTypes.getSelectedItem());
				onConnectionAction.onConnect(driver, getJdbcURL(), getUser(), getPassword());
			}
		});
		
		dbTypes.addItemListener(this);
	}
	
	/**
	 * 获取jdbcURL
	 * @return
	 */
	private String getJdbcURL()
	{
		String dbType = (String)dbTypes.getSelectedItem();
		StringBuffer buffer;
		switch (dbType)
		{
			case DB_MY_SQL:
			{
				//MySQL
				buffer = new StringBuffer("jdbc:mysql://");
				buffer.append(server.getText().trim()).append(":").append(port.getText().trim()).append("/");
				buffer.append(db.getText().trim());
				buffer.append("?serverTimezone=Asia/Shanghai");
				break;
			}
			case DB_SQL_SERVER:
			{
				//SQL Server
				buffer = new StringBuffer("jdbc:sqlserver://");
				buffer.append(server.getText().trim()).append(":").append(port.getText().trim()).append(";");
				buffer.append("databaseName=").append(db.getText().trim());
				break;
			}
			case DB_ORACLE:
			{
				//Oracle
				buffer = new StringBuffer("jdbc:oracle:thin:@");
				buffer.append(server.getText().trim()).append(":").append(port.getText().trim());
				buffer.append(":").append(db.getText().trim());
				break;
			}
			case DB_POSTGRESQL:
			{
				//PostgreSQL
				buffer = new StringBuffer("jdbc:postgresql://");
				buffer.append(server.getText().trim()).append(":").append(port.getText().trim());
				buffer.append("/").append(db.getText().trim());
				break;
			}
			default:
				throw new IllegalArgumentException("Unsupported Database: " + dbType);
		}
		return buffer.toString();
	}

	@Override
	public void itemStateChanged(ItemEvent e)
	{
		if(e.getStateChange() == ItemEvent.SELECTED)
		{
			String item = (String)e.getItem();
			port.setText(portsTable.get(item));
		}
	}

	/**
	 * 获取账号
	 * @return
	 */
	private String getUser()
	{
		return user.getText();
	}
	
	/**
	 * 获取密码
	 * @return
	 */
	private String getPassword()
	{
		return new String(password.getPassword());
	}
	
	public void setConnectionAction(ConnectionAction action)
	{
		this.onConnectionAction = action;
	}
}
